//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#if _MSC_VER > 1000
#pragma once
#endif

#ifndef __PSEUDOTHREAD_H__
#define __PSEUDOTHREAD_H__

#include <elasys_server.h>
#include <interlocked.h>
#include "pobject.h"

#define ELAURA_INVALID_TID ((ThreadId)-1)

class CPseudoThread: public PseudoObject, public IThread
{
public:
    PInterface GetObject() { return (IThread *) this; }
    Boolean Compare(PVoid pCompareData)
    { return (m_pProxy == (IThread *)pCompareData) ? TRUE : FALSE; }

public:
    CARAPI_(PInterface) Probe(
        /* [in] */ REIID riid);

    CARAPI_(UInt32) AddRef();

    CARAPI_(UInt32) Release();

    CARAPI Aggregate(
        /* [in] */ AggrType aggrType,
        /* [in] */ PInterface pObject);

    CARAPI GetDomain(
        /* [out] */ PInterface *ppObject);

    CARAPI Start();

    CARAPI Suspend();

    CARAPI Resume();

    CARAPI Join(
        /* [in] */ Millisecond32 timeout,
        /* [out] */ WaitResult *pResult);

    CARAPI Interrupt();

    CARAPI Abort();

    CARAPI Quit();

    CARAPI SetPriority(
        /* [in] */ ThreadPriority priority);

    CARAPI GetPriority(
        /* [out] */ ThreadPriority * pPriority);

    CARAPI GetId(
        /* [out] */ ThreadId * pTid);

    CARAPI SetName(
        /* [in] */ WString name);

    CARAPI GetName(
        /* [out] */ WStringBuf * pName);

    CARAPI GetState(
        /* [out] */ ThreadState * pState);

    CARAPI GetQuitCode(
        /* [out] */ QuitCode * pQuitCode);

    CARAPI GetStartTime(
        /* [out] */ SystemTime * pTime);

    CARAPI GetQuitTime(
        /* [out] */ SystemTime * pTime);

    CARAPI GetProcessorTimes(
        /* [out] */ Millisecond32 * pUserTime,
        /* [out] */ Millisecond32 * pKernelTime);

public:
    CPseudoThread(ProcessId ownerPid, IThread * pProxy)
                : m_ownerPid(ownerPid),
                  m_threadId(0),
                  m_pProxy(pProxy),
                  m_hLock(NULL) {DLinkNode::Initialize();}

    virtual ~CPseudoThread();

    ECode Initialize();

private:
    ProcessId   m_ownerPid;

    ThreadId    m_threadId;
    IThread *   m_pProxy;
    PVoid       m_hLock;

private:
    Interlocked  m_Refs;
};

class CPseudoThreadFactory: public PseudoObjectFactory
{
public:
    ECode CreateObject(
        /* [out] */ PseudoObject ** ppPseudoObject);

    Boolean Compare(
        /* [in] */ PseudoObject * pPseudoObject)
    { return pPseudoObject->Compare((PVoid)m_pProxy); }

    PseudoObjectType GetType() { return PseudoObjectType_Thread; }

public:
    CPseudoThreadFactory(ProcessId processId, IThread * pProxy)
                       : m_processId(processId),
                         m_pProxy(pProxy) {}

private:
    ProcessId m_processId;
    IThread * m_pProxy;
};

#endif // __PSEUDOTHREAD_H__
